home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 June: Reference Library / Dev.CD Jun 96 RL / Dev.CD Jun 96 RL.toast / Technical Documentation / develop / develop Issue 24 / develop Issue 24 code / Scriptable Database 1.0a15 / Base / PseudoRandom.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-19  |  2.1 KB  |  96 lines  |  [TEXT/CWIE]

  1. #include "PseudoRandom.h"
  2.  
  3. UInt32 RandomLong();
  4. UInt32 RandomRandomLong();
  5.  
  6. UInt32 gRandomSeed = 0;
  7.  
  8. void SetRandomSeed(UInt32 seed)
  9. {
  10.     gRandomSeed = seed;
  11. }
  12.  
  13. UInt32 RandomLong()
  14. {
  15.     gRandomSeed = (gRandomSeed * 1103515245) + 12345;
  16.     
  17.     return gRandomSeed;
  18. }
  19.  
  20. //
  21. // No, I'm not sure this makes the output any more random
  22. // (it does spread the TickCount bits around, though)
  23. //
  24. UInt32 RandomRandomLong()
  25. {
  26.     return RandomLong() ^ ((RandomLong() << 8) & 0x00FFFF00) ^ (RandomLong() << 16);
  27. }
  28.  
  29. //
  30. // No, I'm not sure this makes the output any more random
  31. //
  32. UInt32 PseudoRandomLong()
  33. {
  34.     UInt32 rand1 = RandomRandomLong();
  35.     UInt32 rand2 = RandomRandomLong();
  36.     UInt32 mask = RandomRandomLong();
  37.     
  38.     //
  39.     // Any set bit in 'mask' selects the bit from rand1;
  40.     // any clear bit in 'mask' selects the bit from rand2.
  41.     //
  42.     return ((rand1 ^ rand2) & mask) ^ rand2;
  43. }
  44.  
  45. UInt32 PseudoRandomFromZeroToN(UInt32 n)
  46. {
  47.     UInt32 result = 0;
  48.     
  49.     //
  50.     // Special checking for N == max long integer
  51.     // (Speed optimization, plus avoids a divide-by-zero)
  52.     //
  53.     if(n == 0xFFFFFFFF)
  54.         result = PseudoRandomLong();
  55.     if(n > 0)
  56.     {
  57.         //
  58.         // Some might find it acceptable to simply modulo
  59.         // the result with n.  This is no good, however,
  60.         // because it does not give a good linear distribution.
  61.         // There will (usually) be some section at the top
  62.         // of the number space that maps to the lower portion
  63.         // of n, making small values of n oh-so-slightly more
  64.         // probably than the high values of n.
  65.         //
  66.         UInt32 highestAcceptable = ((0xFFFFFFFF / (n+1)) * (n+1)) - 1;
  67.         
  68.         //
  69.         // Trim off the top end of the range to obtain a
  70.         // flat linear distribution.
  71.         //
  72.         // n.b. This assumes that PseudoRandomLong returns
  73.         // numbers distributed linearly, something that I
  74.         // hope is true, but certainly have not proved.
  75.         //
  76.         do
  77.         {
  78.             result = PseudoRandomLong();
  79.         } while(result > highestAcceptable);
  80.         
  81.         //
  82.         // Now that we have a linear distribution,
  83.         // modulo by (n+1) to put the range in
  84.         // 0-n.
  85.         //
  86.         result %= (n+1);
  87.     }
  88.     
  89.     return result;
  90. }
  91.  
  92. UInt32 PseudoRandomFromMToN(UInt32 m, UInt32 n)
  93. {
  94.     return m < n ? PseudoRandomFromZeroToN(n - m) + m : m;
  95. }
  96.